package com.dap.configuration.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.springframework.web.multipart.MultipartFile;

import com.baidu.dsp.common.constant.DataFormatConstants;
import com.baidu.dsp.common.exception.FieldException;
import com.github.knightliao.apollo.utils.io.OsUtil;
import com.github.knightliao.apollo.utils.time.DateUtils;

/**
 * @author dengxiang
 * @version 2014-9-15
 */
public class UnRarZipUtil {

	/**
	 * spring上传解压缩
	 * 
	 * @throws Exception
	 */
	public static List<File> deCompress(MultipartFile file) throws Exception {
		String name = file.getOriginalFilename();
		List<File> list = new ArrayList<File>();
		if (name.contains("zip")) {
			list = UnRarZipUtil.unzip(file);
		} else {
			throw new FieldException("config", "只支持zip格式的压缩包！", null);
		}
		return list;
	}

	/**
	 * 解压zip格式压缩包 
	 */
	private static List<File> unzip(MultipartFile multFile) throws Exception {
		List<File> list = null;
		try {
			String curTime = DateUtils.format(new Date(),
					DataFormatConstants.COMMON_TIME_FORMAT);
			curTime = "tmp" + File.separator + curTime;
			OsUtil.makeDirs(curTime);
			File sourceFile = new File(curTime, "upload.zip");// 源文件ZIP
			File targetFile = new File(curTime, "target");// 目标文件
			targetFile.mkdir();
			FileUtils.writeByteArrayToFile(sourceFile, multFile.getBytes());
			Project p = new Project();
			Expand e = new Expand();
			e.setProject(p);
			e.setSrc(sourceFile);
			e.setOverwrite(false);
			e.setDest(targetFile);
			/*
			 * ant下的zip工具默认压缩编码为UTF-8编码， 而winRAR软件压缩是用的windows默认的GBK或者GB2312编码
			 * 所以解压缩时要制定编码格式
			 */
			e.setEncoding("utf-8");
			e.execute();
			// arr转成list
			File[] arr = targetFile.listFiles();
			list = new ArrayList<File>();
			for (int i = 0; i < arr.length; i++) {
				list.add(arr[i]);
			}
		} catch (Exception e) {
			throw new FieldException("config", "文件解压出错", null);
		}

		return list;
	}

	/****
	 * 压缩文件方法
	 * @param dir
	 * @param fileNamePrefix
	 * @param fileList
	 * @return
	 * @throws IOException
	 * @throws CompressorException
	 */
	public static String tarFiles(String dir, String fileNamePrefix, List<File> fileList)
	        throws IOException, CompressorException {

	        //
	        OsUtil.makeDirs(dir);

	        // 时间
	        String curTime = DateUtils.format(new Date(), DataFormatConstants.COMMON_TIME_FORMAT);

	        // 文件名
	        String outputFilePath = fileNamePrefix + "_" + curTime + ".zip";
	        File outputFile = new File(dir, outputFilePath);

	        FileOutputStream out = null;
	        out = new FileOutputStream(outputFile);

	        //
	        // 进行打包
	        //
	        TarArchiveOutputStream os = new TarArchiveOutputStream(out);
	        for (File file : fileList) {
	            os.putArchiveEntry(new TarArchiveEntry(file, file.getName()));
	            IOUtils.copy(new FileInputStream(file), os);
	            os.closeArchiveEntry();
	        }

	        if (os != null) {
	            try {
	                os.flush();
	                os.close();
	            } catch (IOException e) {
	                throw e;
	            }
	        }

	        return outputFile.getAbsolutePath();
	    }
}
